package searcher;

import java.io.*;
import java.util.ArrayList;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.atomic.AtomicLong;

public class Parser {
    private static final String INPUT_PATH = "C:/Users/Administrator/Desktop/test/jdk-8u341-docs-all/docs/api/";
    private Index index = new Index();
    private AtomicLong t1 = new AtomicLong(0);
    private AtomicLong t2 = new AtomicLong(0);
    //单线程制作索引
//    public void run() {
//        System.out.println("索引制作开始！");
//        long begin = System.currentTimeMillis();
//        ArrayList<File> fileList = new ArrayList<>();
//        enumFile(INPUT_PATH, fileList);
//        long endEnumFile = System.currentTimeMillis();
//        System.out.println("枚举文件完毕！消耗时间：" + (endEnumFile - begin) + " ms");
////        System.out.println(fileList);
////        System.out.println(fileList.size());
//
//        for (File f : fileList) {
//            System.out.println("开始解析：" + f.getAbsolutePath());
//            parseHtml(f);
//        }
//        long endFor = System.currentTimeMillis();
//        System.out.println("循环遍历文件完毕！ 消耗时间：" + (endFor - begin) + " ms");
//        index.save();
//        long end = System.currentTimeMillis();
//        System.out.println("索引制作结束！消耗时间为：" + (end - begin) + " ms ");
//    }

    //多线程制作索引
    public void runByThread() throws InterruptedException {
        long begin = System.currentTimeMillis();
        System.out.println("索引制作开始！");

        ArrayList<File> files = new ArrayList<>();
        enumFile(INPUT_PATH, files);
        ExecutorService executorService = Executors.newFixedThreadPool(8);
        CountDownLatch latch = new CountDownLatch(files.size());
        for (File f : files) {
            executorService.submit(new Runnable() {
                @Override
                public void run() {
                    System.out.println("解析 ：" + f.getAbsolutePath());
                    parseHtml(f);
                    latch.countDown();
                }
            });
        }
        latch.await();
        executorService.shutdown();
        index.save();
        long end = System.currentTimeMillis();
        System.out.println("索引制作结束！ 消耗时间：" + (end - begin) + " ms");
        System.out.println("t1: " + t1 + " t2: " + t2);
    }

    private void parseHtml(File f) {
        String title = parseTitle(f);
        String url = parseUrl(f);
        long begin = System.nanoTime();
//        String content = parseContent(f);
        String content = parseContentByRegex(f);
        long mid = System.nanoTime();
        index.addDoc(title, url, content);
        long end = System.nanoTime();
        t1.addAndGet(mid - begin);
        t2.addAndGet(end - mid);
        System.out.println();
    }

    public String parseContent(File f) {
        try (BufferedReader bufferedReader = new BufferedReader(new FileReader(f), 1024 * 1024)) {
            boolean isCopy = false;
            StringBuilder content = new StringBuilder();
            while (true) {
                int ret = bufferedReader.read();
                if (ret == -1) {
                    break;
                }
                char c = (char) ret;
                if (isCopy) {
                    if (c == '<') {
                        isCopy = false;
                        continue;
                    }
                    if (c == '\n' || c == '\r') {
                        c = ' ';
                    }
                    content.append(c);
                } else {
                    if (c == '>') {
                        isCopy = true;
                    }
                }
            }
            return content.toString();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return "";
    }

    private String readFile(File f) {
        try (BufferedReader bufferedReader = new BufferedReader(new FileReader(f))) {
            StringBuilder content = new StringBuilder();
            while (true) {
                int ret = bufferedReader.read();
                if (ret == -1) {
                    break;
                }
                char c = (char) ret;
                if (c == '\n' || c == '\r') {
                    c = ' ';
                }
                content.append(c);
            }
            return content.toString();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return "";
    }

    public String parseContentByRegex(File f) {
        String content = readFile(f);
        content = content.replaceAll("<script.*?>(.*?)</script>", " ");
        content = content.replaceAll("<.*?>", " ");
        content = content.replaceAll("\\s+", " ");
        return content;
    }

    private String parseUrl(File f) {
        String part1 = "https://docs.oracle.com/javase/8/docs/api/";
        String part2 = f.getAbsolutePath().substring(INPUT_PATH.length());
        return part1 + part2;
    }

    private String parseTitle(File f) {
        String name = f.getName();
        return name.substring(0, name.length() - ".html".length());
    }

    private void enumFile(String inputPath, ArrayList<File> fileList) {
        File rootPath = new File(inputPath);
        File[] files = rootPath.listFiles();

        for (File f : files) {
            if (f.isDirectory()) {
                enumFile(f.getAbsolutePath(), fileList);
            } else {
                if (f.getAbsolutePath().endsWith(".html")) {
                    fileList.add(f);
                }
            }
        }
    }

    public static void main(String[] args) throws InterruptedException {
        Parser parser = new Parser();
//        parser.run();
        parser.runByThread();
    }
}
